﻿using System;
using System.Collections;
using System.Linq;
using System.ComponentModel; 
using System.Text;

namespace Tema_inginerie
{
   public sealed class CarPool
    {
       //clasa se bazeaza pe proiectarea de tip Singleton
        private Queue pool = new Queue();
        private Hashtable objPool = new Hashtable();
        private static readonly object objLock = new object();
        private const int poolSize = 10;
        private int objCount = 0;
        private static CarPool instance = null;

       //constructor privat pentru a preveni instantiera
        private CarPool()
        {
       
        }

       //cosntructorul static care este apelat o singura data pe tot parcursul rularii aplicatiei
        public static CarPool getInstance() 
        {
            if (instance == null) instance = new CarPool();
            return instance;
        }
      
       //creare obiecte si adaugare in pool
        public void CreateObjects(object obj)
        {
            object _obj = obj;
            objCount = 0;
            pool.Clear();
            objPool.Clear();
            for (int objCounter = 0; objCounter < poolSize; objCounter++)
            {
                _obj = new object();
                lock (objLock)
                {
                    objPool.Add(_obj.GetHashCode(), _obj);
                    pool.Enqueue(_obj);
                    objCount++;
                }
            }
        }


       //adaugare obiect in pool
        public bool AddObj(object obj)
        {
            if (objCount == poolSize) return false;
            lock (objLock)
            {
                objPool.Add(obj.GetHashCode(), obj); 
                pool.Enqueue(obj);
                objCount++;
            }
            return true;
        }
       //stergere obiect din pool de la sfarsitul cozii
        public object ReleaseObject()
        {
            if (objCount == 0) return null;
            lock (objLock)
            {
                objPool.Remove(pool.Dequeue().GetHashCode());
                objCount--;
                if (pool.Count > 0)
                    return pool.Dequeue();
            }
            return null;
        }
       //stergere obiect  din pool
       public object ReleaseObject(object obj)
        {
            if (objCount == 0)
                return null;

            lock (objLock)
            {
                objPool.Remove(obj.GetHashCode());
                objCount--;
                RePopulate();
                return obj;
            }
        }
      //repopulare coada dupa ce un obiect a fost sters
       private void RePopulate()
       {
           if (pool.Count > 0)
               pool.Clear();

           foreach (int key in objPool.Keys)
           {
               pool.Enqueue(objPool[key]);
           }
          
       }

       //numarul curent al obiectelor in pool
       public int CurrentObjectsInPool
       {
           get
           {
               return objCount;
           }
       }
       //numarul maxim de obiecte din pool
       public int MaxObjectsInPool
       {
           get
           {
               return poolSize;
           }
       }
     
    }
}
